package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.apis.article.IArticleClient;
import com.heima.apis.userService.IUserServiceClinent;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.comment.service.CommentService;
import com.heima.model.comment.dtos.CommentVo;
import com.heima.model.comment.dtos.LikeCommentDto;
import com.heima.model.comment.dtos.QueryCommentsDto;
import com.heima.model.comment.dtos.SaveCommentDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.CommentUserDto;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.thread.WmThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author tujian
 * @Date 2022年03月24日 18:24:25
 */
@Service
@Transactional
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IUserServiceClinent iUserServiceClinent;

    @Autowired
    private IWemediaClient iWemediaClient;
    /**
     * 保存评论
     */
    @Override
    public ResponseResult save(SaveCommentDto dto) {
        log.info("保存评论");
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (null == WmThreadLocalUtil.getUser().getId()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_REQUIRE, "请登录后再试");
        }
        //内容审核
        if (dto.getContent().length() >= 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论过长");
        }
        //自管理的敏感词过滤
        //获取所有的敏感词
        ResponseResult responseResult = iWemediaClient.querySensitiveAll();
        String s = JSON.toJSONString(responseResult.getData());
        List<String> sensitiveList = JSON.parseObject(s, List.class);
        sensitiveList=sensitiveList.stream().filter(item->item!=null).collect(Collectors.toList());
        //初始化敏感词库
        SensitiveWordUtil.initMap(sensitiveList);
        //查看是否包含敏感词
        Map<String, Integer> map = SensitiveWordUtil.matchWords(dto.getContent());
        if(map.size() >0){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"敏感字符");
        }
        //查询当前用户
        Integer id = WmThreadLocalUtil.getUser().getId();
        CommentUserDto commentUserDto = new CommentUserDto();
        commentUserDto.setId(id);

        Object data = iUserServiceClinent.getUserRealnameUser(commentUserDto).getData();
        String s1 = JSON.toJSONString(data);
        commentUserDto = JSON.parseObject(s1, CommentUserDto.class);

        CommentVo commentVo = new CommentVo();
        //评论id
        commentVo.setId(UUID.randomUUID().toString());
        //文章id
        commentVo.setArticleId(dto.getArticleId());
        //评论人名字image
        commentVo.setAuthorName(commentUserDto.getName());
        //评论人头像
        commentVo.setImage(commentUserDto.getImage());
        //评论内容
        commentVo.setContent(dto.getContent());
        //点赞
        commentVo.setOperation((short) 1);
        //点赞数
        commentVo.setLikes(0);
        //评论时间
        commentVo.setCreatedTime(new Date());
        //回复数
        commentVo.setReply(0);
        //保存
        mongoTemplate.save(commentVo);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 查询评论
     *
     * @param dto
     */
    @Override
    public ResponseResult load(QueryCommentsDto dto) {
        log.info("查询评论");
        if (dto == null) {
            return PageResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //时间校验
        if (dto.getMinDate() == null) {
            dto.setMinDate(new Date());
        }
        //查询总数
        Criteria criteria = Criteria.where("ArticleId").is(dto.getArticleId());
        Criteria criteria1 = Criteria.where("createdTime").lt(dto.getMinDate());

//        Query query = new Query(criteria);
//        long count = mongoTemplate.count(query, CommentVo.class);
//        System.out.println(count);
        //2、
        Query queryLimit = new Query(criteria).addCriteria(criteria1).with(Sort.by(Sort.Order.desc("createdTime")));
        List<CommentVo> commentVo = mongoTemplate.find(queryLimit, CommentVo.class);

        log.info(String.valueOf(commentVo));
        return ResponseResult.okResult(commentVo);
    }

    /**
     * 点赞
     *
     * @param dto
     */
    @Override
    public ResponseResult like(LikeCommentDto dto) {
        log.info("点赞");
        Query query = new Query(Criteria.where("Id").is(dto.getCommentId()));
        CommentVo commentVo = mongoTemplate.findOne(query, CommentVo.class);
        Map<String, Integer> map = new HashMap<>();

        if (commentVo == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //修改状态
        Update update = new Update();
        short operation = commentVo.getOperation();
        int likeCount = commentVo.getLikes();
        if (operation == 0) {
            update.set("operation", (short) 1);
            log.info("减少");
            likeCount = likeCount - 1;
        } else {
            update.set("operation", (short) 0);
            log.info("增加");
            likeCount = likeCount + 1;
        }
        update.set("likes", likeCount);
        mongoTemplate.updateFirst(query, update, CommentVo.class);
        map.put("likes", likeCount);
        log.info(String.valueOf(map));

        return ResponseResult.okResult(map);
    }
}
